﻿using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using CommonUtility;
using Microsoft.AspNetCore.Http;
using System;
using System.Data;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using WPay.Infrastructure.Unity;
using static Utility.UploadFileHelper;

namespace Utility
{
    public class AwsHelper
    {
        static IAmazonS3 client;
        //定义访问秘钥
        private static readonly string _awsAccessKey = ConfigManage.GetConfigByKey("AwsAccessKey"); //ReadConfig.ReadAppSetting("AwsAccessKey"); //"AKIAOSYUDOFSXJ4R7L6A";
        //定义私密秘钥
        private static readonly string _awsSecretKey = ConfigManage.GetConfigByKey("AwsSecretKey");//ReadConfig.ReadAppSetting("AwsSecretKey");
        private static readonly string s3adds = ConfigManage.GetConfigByKey("s3adds");//北京：cn-north-1  宁夏：cn-northwest-1
        private static readonly string s3bucketName = ConfigManage.GetConfigByKey("s3bucketName");

        /// <summary>
        /// 保存信息到亚马逊
        /// </summary>
        /// <param name="html">需要保存的信息</param>
        /// <param name="CpnID">企业号</param>
        /// <returns></returns>
        public static string SaveHtml(string html, DataBusiness emue, string writeName, string CpnID)
        {
            String htmlstr = html;
            if (!String.IsNullOrEmpty(htmlstr))
            {
                htmlstr = HttpUtility.UrlEncode(htmlstr);
                htmlstr = Write(String.Empty, writeName, htmlstr);
                if (!String.IsNullOrEmpty(htmlstr))
                {
                    htmlstr = FileToS3ByPath(htmlstr, UploadFileHelper.DataType.File, emue, CpnID);
                }
            }
            return htmlstr;
        }
        public static string FileToS3ByPath(String filePath, DataType dtype, DataBusiness dbtype, String CpnID)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = $"https://s3.{s3adds}.amazonaws.com.cn/"
                };
                //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                // AmazonS3Client test = new AmazonS3Client(_awsAccessKey, _awsSecretKey, Amazon.RegionEndpoint.CNNorth1);
                //获取文件保存地址
                //空间保存路径
                string _bucketName = $"{s3bucketName}/ActConfig/" + CpnID + "/" + dtype.ToString() + "/" + dbtype.ToString() + "/" + DateTime.Now.ToString("yyyyMM");
                //获取文件名称
                string fileName = filePath.Split('\\')[filePath.Split('\\').Length - 1].Split('.')[0];
                //获取文件后缀名
                string fileExt = filePath.Split('\\')[filePath.Split('\\').Length - 1].Split('.')[0].ToLower();
                //获取自定义文件名
                //string uploadFileName = DateTime.Now.ToString("yyyyMMddhhmmss") + r.Next(100000, 999999) + fileExt;
                string uploadFileName = filePath.Split('\\')[filePath.Split('\\').Length - 1];
                //定义一个request
                var request = new PutObjectRequest()
                {
                    BucketName = _bucketName,
                    CannedACL = S3CannedACL.PublicReadWrite,
                    Key = uploadFileName,
                    InputStream = new StreamReader(filePath, System.Text.Encoding.UTF8).BaseStream,
                };
                var str = UpLoad(request, _bucketName, uploadFileName);
                File.Delete(filePath);
                return str;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message);
                return String.Empty;
            }
        }
        public static string FileToS3ByPath(String filePath, string floder, String CpnID)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = $"https://s3.{s3adds}.amazonaws.com.cn/"
                };
                //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                // AmazonS3Client test = new AmazonS3Client(_awsAccessKey, _awsSecretKey, Amazon.RegionEndpoint.CNNorth1);
                //获取文件保存地址
                //空间保存路径
                string _bucketName = $"{s3bucketName}/{floder}/" + CpnID;
                //获取文件名称
                string fileName = filePath.Split('\\')[filePath.Split('\\').Length - 1].Split('.')[0];
                //获取文件后缀名
                string fileExt = filePath.Split('\\')[filePath.Split('\\').Length - 1].Split('.')[0].ToLower();
                //获取自定义文件名
                //string uploadFileName = DateTime.Now.ToString("yyyyMMddhhmmss") + r.Next(100000, 999999) + fileExt;
                string uploadFileName = filePath.Split('\\')[filePath.Split('\\').Length - 1];
                //定义一个request
                var request = new PutObjectRequest()
                {
                    BucketName = _bucketName,
                    CannedACL = S3CannedACL.PublicReadWrite,
                    Key = uploadFileName,
                    InputStream = new StreamReader(filePath, System.Text.Encoding.UTF8).BaseStream,
                };
                var str = UpLoad(request, _bucketName, uploadFileName);
                File.Delete(filePath);
                return str;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message);
                return String.Empty;
            }
        }

        public static string FileToS3ByStream(Stream BaseStream, string floder, string name, String CpnID, string bucketname = null)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = $"https://s3.{s3adds}.amazonaws.com.cn/"
                };
                //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                // AmazonS3Client test = new AmazonS3Client(_awsAccessKey, _awsSecretKey, Amazon.RegionEndpoint.CNNorth1);
                //获取文件保存地址
                //空间保存路径
                string _bucketName = !string.IsNullOrWhiteSpace(bucketname) ? bucketname : ($"{s3bucketName}/{floder}/" + CpnID);
                //string uploadFileName = DateTime.Now.ToString("yyyyMMddhhmmss") + r.Next(100000, 999999) + fileExt;
                string uploadFileName = name;
                //定义一个request
                var request = new PutObjectRequest()
                {
                    BucketName = _bucketName,
                    CannedACL = S3CannedACL.PublicReadWrite,
                    Key = uploadFileName,
                    InputStream = BaseStream,
                };
                var str = UpLoad(request, _bucketName, uploadFileName);
                return str;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message);
                return String.Empty;
            }
        }

        /// <summary>
        /// 保存信息到亚马逊(用于支付订单日志)
        /// </summary>
        /// <param name="html">需要保存的信息</param>
        /// <param name="CpnID">企业号</param>
        public static string SaveHtml(DataTable dt, DataBusiness emue, string CpnID, string date, string act, string writeName = "OthpayRecord")
        {
            String htmlstr = "";
            string logName = "";
            //日志存储路径
            string fileDirectory = Directory.GetCurrentDirectory() + ("/App_Data/" + writeName + "/");
            //日志文件名
            if (logName == String.Empty)
            {
                logName = act + "[" + Guid.NewGuid().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + "]" + ".csv";
            }
            //日志存储
            string fileName = fileDirectory + logName;
            //htmlstr = Write(String.Empty, writeName, htmlstr);
            CSVFileHelper.SaveCSV(dt, fileName);
            if (!String.IsNullOrEmpty(fileName))
            {
                htmlstr = FileToS3ByPath(fileName, UploadFileHelper.DataType.File, emue, CpnID, date, act, writeName);
            }
            return htmlstr;
        }
        public static string FileToS3ByPath(String filePath, DataType dtype, DataBusiness dbtype, String CpnID, string date, string act, string name)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = $"https://s3.{s3adds}.amazonaws.com.cn/",
                };
                //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                // AmazonS3Client test = new AmazonS3Client(_awsAccessKey, _awsSecretKey, Amazon.RegionEndpoint.CNNorth1);
                //获取文件保存地址
                //空间保存路径
                string _bucketName = $"{s3bucketName}/{name}/cpn={CpnID}/year={Convert.ToDateTime(date).Year}/month={Convert.ToDateTime(date).Month}/day={Convert.ToDateTime(date).Day}";
                //获取文件名称
                string uploadFileName = $"{act}.csv";
                //定义一个request
                var request = new PutObjectRequest()
                {
                    BucketName = _bucketName,
                    CannedACL = S3CannedACL.PublicReadWrite,
                    Key = uploadFileName,
                    InputStream = new StreamReader(filePath, System.Text.Encoding.UTF8).BaseStream,
                };
                var str = UpLoad(request, _bucketName, uploadFileName);
                File.Delete(filePath);
                return str;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message + e.InnerException?.Message);
                return String.Empty;
            }
        }


        public static string FileToS3REC(String filePath, String CpnID, string date, string name)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = $"https://s3.{s3adds}.amazonaws.com.cn/",
                };
                //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                // AmazonS3Client test = new AmazonS3Client(_awsAccessKey, _awsSecretKey, Amazon.RegionEndpoint.CNNorth1);
                //获取文件保存地址
                //空间保存路径
                string _bucketName = $"{s3bucketName}/Rec/cpn={CpnID}/year={Convert.ToDateTime(date).Year}/month={Convert.ToDateTime(date).Month}/day={Convert.ToDateTime(date).Day}";
                //获取文件名称
                string uploadFileName = name;
                //定义一个request
                var request = new PutObjectRequest()
                {
                    BucketName = _bucketName,
                    CannedACL = S3CannedACL.PublicReadWrite,
                    Key = uploadFileName,
                    InputStream = new StreamReader(filePath, System.Text.Encoding.UTF8).BaseStream,
                };
                var str = UpLoad(request, _bucketName, uploadFileName);
                File.Delete(filePath);
                return str;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message + e.InnerException?.Message);
                return String.Empty;
            }
        }
        public static string FileToS3ByPathForname(String filePath, DataType dtype, DataBusiness dbtype, String CpnID, string date, string act, string name, string filename)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = $"https://s3.{s3adds}.amazonaws.com.cn/",
                };
                //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                // AmazonS3Client test = new AmazonS3Client(_awsAccessKey, _awsSecretKey, Amazon.RegionEndpoint.CNNorth1);
                //获取文件保存地址
                //空间保存路径
                string _bucketName = $"{s3bucketName}/{name}/cpn={CpnID}/year={Convert.ToDateTime(date).Year}/month={Convert.ToDateTime(date).Month}/day={Convert.ToDateTime(date).Day}";
                //获取文件名称
                // string fileName = filePath.Split('\\')[filePath.Split('\\').Length - 1].Split('.')[0];
                //获取文件后缀名
                //string fileExt = filePath.Split('\\')[filePath.Split('\\').Length - 1].Split('.')[0].ToLower();
                //获取自定义文件名
                //string uploadFileName = DateTime.Now.ToString("yyyyMMddhhmmss") + r.Next(100000, 999999) + fileExt;
                //string uploadFileName = filePath.Split('\\')[filePath.Split('\\').Length - 1];
                string uploadFileName = $"{filename}.csv";
                //定义一个request
                var request = new PutObjectRequest()
                {
                    BucketName = _bucketName,
                    CannedACL = S3CannedACL.PublicReadWrite,
                    Key = uploadFileName,
                    InputStream = new StreamReader(filePath, System.Text.Encoding.UTF8).BaseStream,
                };
                var str = UpLoad(request, _bucketName, uploadFileName);
                File.Delete(filePath);
                return str;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message + e.InnerException?.Message);
                return String.Empty;
            }
        }
        /// <summary>
        /// 上传亚马逊路径
        /// </summary>
        /// <param name="file">上传的文件</param>
        /// <param name="dtype">文件类型</param>
        /// <param name="dbtype"></param>
        /// <param name="CpnID"></param>
        /// <returns></returns>
        public static String FileToS3ByHttpPostedFile(IFormFile file, DataType dtype, DataBusiness dbtype, String CpnID = null)
        {
            // 文件上传亚马逊路径：CPNID > 文件类型 > 模块名 > 时间（年月：200706）

            AmazonS3Config config = new AmazonS3Config()
            {
                ServiceURL = "https://s3." + s3adds + ".amazonaws.com.cn/"
            };
            //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
            client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
            //空间保存路径
            CpnID = string.IsNullOrWhiteSpace(CpnID) ? "system" : CpnID;
            string _bucketName = s3bucketName + "/" + CpnID + "/" + dtype.ToString() + "/" + dbtype.ToString() + "/" + DateTime.Now.ToString("yyyyMM");
            //获取文件名称
            string fileName = file.FileName;
            //获取文件后缀名
            string fileExt = Path.GetExtension(fileName).ToLower();
            //获取自定义文件名
            string uploadFileName = DateTime.Now.ToString("yyyyMMddhhmmssfff") + new Random().Next(100000, 999999) + fileExt;
            //定义一个request
            var reader = new StreamReader(file.OpenReadStream());
            var request = new PutObjectRequest()
            {
                BucketName = _bucketName,
                CannedACL = S3CannedACL.PublicReadWrite,
                Key = uploadFileName,
                InputStream = reader.BaseStream,
            };
            return UpLoad(request, _bucketName, uploadFileName);
        }
        public static String FileToS3ByHttpPostedFile2(IFormFile file, DataType dtype, DataBusiness dbtype, String CpnID, string date, string act, string name)
        {
            // 文件上传亚马逊路径：CPNID > 文件类型 > 模块名 > 时间（年月：200706）

            AmazonS3Config config = new AmazonS3Config()
            {
                ServiceURL = "https://s3." + s3adds + ".amazonaws.com.cn/"
            };
            //创建一个s3的客户端操作对象（需要amazon提供的密钥）  
            client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
            string _bucketName = $"{s3bucketName}/{name}/cpn={CpnID}/year={Convert.ToDateTime(date).Year}/month={Convert.ToDateTime(date).Month}/day={Convert.ToDateTime(date).Day}";
            string uploadFileName = $"{act}.csv";
            //定义一个request
            var reader = new StreamReader(file.OpenReadStream());
            var request = new PutObjectRequest()
            {
                BucketName = _bucketName,
                CannedACL = S3CannedACL.PublicReadWrite,
                Key = uploadFileName,
                InputStream = reader.BaseStream,
            };
            return UpLoad(request, _bucketName, uploadFileName);
        }


        public static String UpLoad(PutObjectRequest request, String bucketName, String uploadFileName)
        {
            try
            {
                var result = client.PutObjectAsync(request).Result;
                GetPreSignedUrlRequest gprequest = new GetPreSignedUrlRequest();
                gprequest.BucketName = bucketName;
                gprequest.Key = uploadFileName;
                gprequest.Expires = DateTime.Now.AddDays(7);
                string url = client.GetPreSignedURL(gprequest).Split('?')[0];
                LoggerHelper.Log("Succes_Url", url);
                return url;
            }
            catch (AmazonS3Exception e)
            {
                LoggerHelper.Log("UploadToS3", e.Message + e.InnerException?.Message);
                return String.Empty;
            }
            catch (Exception ex)
            {
                LoggerHelper.Log("Upload", ex.Message + ex.InnerException?.Message);
                throw;
            }
        }
        public static String Write(String logName, String folderName, string logMsg)
        {
            //日志存储路径
            string fileDirectory = Directory.GetCurrentDirectory() + ("/App_Data/" + folderName + "/");
            //日志文件名
            if (logName == String.Empty)
            {
                logName = Guid.NewGuid().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + ".txt";
            }
            //日志存储
            string fileName = fileDirectory + logName;
            try
            {
                if (!Directory.Exists(fileDirectory))
                {
                    Directory.CreateDirectory(fileDirectory);
                }
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
                StreamWriter sw;
                sw = File.CreateText(fileName);
                sw.Write(logMsg);
                sw.Close();
                return fileName;
            }
            catch
            {
                return String.Empty;
            }

        }
        /// <summary>
        /// 获取亚马逊文件服务器文件内容
        /// </summary>
        /// <param name="url">亚马逊服务器文件地址</param>
        /// <returns></returns>
        public static string GetAWSContent(string url)
        {
            var retStr = String.Empty;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "text/html;charset=UTF-8";

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
            retStr = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();

            if (!String.IsNullOrEmpty(retStr))
            {
                retStr = HttpUtility.UrlDecode(retStr);
                return retStr;
            }
            return "";
        }
        /// <summary>
        /// 获取存储桶
        /// </summary>
        /// <param name="CpnID">企业号</param>
        /// <param name="business">表名</param>
        /// <returns></returns>
        public static String GetbucketName(string CpnID, DataBusiness business, DateTime dt)
        {
            string _bucketName = s3bucketName + "/" + business.ToString() + "/cpn=" + CpnID + "/year=" + dt.Year.ToString() + "/month=" + dt.Month.ToString() + "/day=" + dt.Day.ToString();
            return _bucketName;
        }
        /// <summary>
        /// 下载亚马逊上的文件
        /// </summary>
        /// <param name="file">文件名</param>
        /// <param name="type">文件类型{Image：图片，File：文件}</param>
        /// <param name="source">文件来源{Retailers：零售商，Provider：供应商，Platform：平台}</param>
        /// <returns></returns>
        public static void DownloadFile(string CpnID, DateTime date, string floadername, string filepath, string uploadFileName)
        {
            try
            {
                Random r = new Random();
                //获取上传地址
                AmazonS3Config config = new AmazonS3Config()
                {
                    ServiceURL = "https://s3." + s3adds + ".amazonaws.com.cn/"
                };
                //空间保存路径
                string _bucketName = $"{s3bucketName}/{floadername}/cpn={CpnID}/year={Convert.ToDateTime(date).Year}/month={Convert.ToDateTime(date).Month}/day={Convert.ToDateTime(date).Day}";
                client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, config);
                var request = new GetObjectRequest()
                {
                    BucketName = _bucketName,
                    Key = uploadFileName,

                };
                var response = client.GetObjectAsync(request).Result;
                var memoryStream = new MemoryStream();
                response.ResponseStream.CopyTo(memoryStream);
                memoryStream.Position = 0;
                if (!File.Exists(filepath))
                {
                    //防止产生“另一个进程访问”出错，不能直接Create
                    using (var fst = File.Create(filepath))
                    {
                        fst.Flush();
                    }
                }
                FileStream fs = new FileStream(filepath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                //创建本地文件写入流
                //Stream stream = new FileStream(tempFile, FileMode.Create);
                byte[] bArr = new byte[1024];
                int size = memoryStream.Read(bArr, 0, (int)bArr.Length);
                while (size > 0)
                {
                    //stream.Write(bArr, 0, size);
                    fs.Write(bArr, 0, size);
                    size = memoryStream.Read(bArr, 0, (int)bArr.Length);
                }
                //stream.Close();
                fs.Close();
            }
            catch (AmazonS3Exception e)
            {
                ErrorLog.WriteLog("AmazonS3Exception-ex", JSONSerializer.Serialize(e));

            }
        }


    }
    public class UploadFileHelper
    {


        public enum DataType
        {
            [System.ComponentModel.Description("图片")]
            Image,
            [System.ComponentModel.Description("文件")]
            File
        }

        public enum DataBusiness
        {
            Vote,
            Store,
            Gds,//商品基础资料
            GdsCnvrt,//上架目录
            ClmLst,
            Common,
            MbrPrv,
            Lkdrw,
            Freply,
            TknInf,
            PgConfig,
            PgMenu,
            Wpay,
            ProductDocTyp,
            CommProblem,//常见问题
            Other,//其它
            Alipay,
        }

        /// <summary>
        /// 文件所属
        /// </summary>
        public enum DataSource
        {
            [System.ComponentModel.Description("零售商")]
            Retailers,
            [System.ComponentModel.Description("供应商")]
            Provider,
            [System.ComponentModel.Description("平台")]
            Platform
        }

    }
}
